package site.edody.dframe.plugin;

import net.bytebuddy.implementation.bind.annotation.AllArguments;
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 字符串方法执行器
 * 支持将字符串代码作为方法实现
 */
public class StringMethodExecutor {
    private static final Logger log = LoggerFactory.getLogger(StringMethodExecutor.class);

    // 存储方法实现字符串
    private final Map<String, String> methodImplementations;
    private final CodeBasedDependencyManager dependencyManager;

    public StringMethodExecutor(Map<String, String> methodImplementations, CodeBasedDependencyManager dependencyManager) {
        this.methodImplementations = new HashMap<>(methodImplementations);
        this.dependencyManager = dependencyManager;
    }

    /**
     * 执行方法
     */
    @RuntimeType
    public Object execute(@Origin Method method, @AllArguments Object[] args) throws Exception {
        String methodName = method.getName();
        String implementation = methodImplementations.get(methodName);

        if (implementation == null) {
            // 如果没有提供实现，检查是否是抽象方法
            if (java.lang.reflect.Modifier.isAbstract(method.getModifiers())) {
                throw new UnsupportedOperationException("抽象方法 " + methodName + " 未实现");
            }
            // 对于非抽象方法，返回默认值
            return getDefaultValue(method.getReturnType());
        }

        log.debug("执行方法: {}, 实现: {}", methodName, implementation);

        try {
            return executeConstructorExpression(implementation, method.getReturnType());
        } catch (Exception e) {
            log.error("执行方法 {} 失败: {}", methodName, e.getMessage());
            throw new RuntimeException("执行方法 " + methodName + " 失败: " + e.getMessage(), e);
        }
    }

    /**
     * 执行构造函数表达式
     */
    private Object executeConstructorExpression(String implementation, Class<?> returnType) throws Exception {
        try {
            // 移除 "new " 前缀和末尾的分号（如果有）
            String expression = implementation.trim();
            if (expression.startsWith("new ")) {
                expression = expression.substring(4);
            }
            if (expression.endsWith(";")) {
                expression = expression.substring(0, expression.length() - 1);
            }

            // 解析类名和参数
            int parenIndex = expression.indexOf('(');
            if (parenIndex == -1) {
                throw new RuntimeException("无效的构造函数表达式: " + expression);
            }

            String className = expression.substring(0, parenIndex).trim();
            String paramsStr = expression.substring(parenIndex + 1, expression.lastIndexOf(')'));

            // 使用依赖管理器加载类
            Class<?> targetClass;
            try {
                targetClass = dependencyManager.loadClass(className);
                log.debug("使用依赖管理器成功加载类: {}", className);
            } catch (ClassNotFoundException e) {
                // 如果依赖管理器找不到，尝试系统类加载器
                log.debug("依赖管理器无法加载类 {}，尝试系统类加载器", className);
                targetClass = Class.forName(className);
            }

            // 解析参数
            Object[] constructorArgs = parseParameters(paramsStr);
            log.debug("解析参数完成: {}", Arrays.toString(constructorArgs));

            // 查找匹配的构造函数
            Constructor<?>[] constructors = targetClass.getConstructors();
            log.debug("找到 {} 个构造函数", constructors.length);

            for (Constructor<?> constructor : constructors) {
                Class<?>[] paramTypes = constructor.getParameterTypes();
                log.debug("检查构造函数: {}，参数类型: {}", constructor, Arrays.toString(paramTypes));

                if (paramTypes.length == constructorArgs.length) {
                    boolean compatible = true;
                    for (int i = 0; i < paramTypes.length; i++) {
                        if (constructorArgs[i] != null &&
                                !isCompatibleType(paramTypes[i], constructorArgs[i].getClass())) {
                            compatible = false;
                            log.debug("参数 {} 不兼容: 期望 {}, 实际 {}", i, paramTypes[i], constructorArgs[i].getClass());
                            break;
                        }
                    }
                    if (compatible) {
                        log.debug("找到兼容的构造函数: {}", constructor);
                        return constructor.newInstance(constructorArgs);
                    }
                }
            }

            throw new RuntimeException("未找到匹配的构造函数: " + expression + "，参数: " + Arrays.toString(constructorArgs));

        } catch (Exception e) {
            throw new RuntimeException("执行构造函数表达式失败: " + implementation, e);
        }
    }

    /**
     * 解析参数字符串
     */
    private Object[] parseParameters(String paramsStr) {
        if (paramsStr.trim().isEmpty()) {
            return new Object[0];
        }

        List<Object> params = new ArrayList<>();
        StringBuilder currentParam = new StringBuilder();
        boolean inString = false;
        char stringChar = '"';

        for (int i = 0; i < paramsStr.length(); i++) {
            char c = paramsStr.charAt(i);

            if (inString) {
                if (c == stringChar) {
                    inString = false;
                    params.add(currentParam.toString());
                    currentParam = new StringBuilder();
                    // 跳过逗号和空格
                    while (i + 1 < paramsStr.length() &&
                            (paramsStr.charAt(i + 1) == ',' || Character.isWhitespace(paramsStr.charAt(i + 1)))) {
                        i++;
                    }
                } else {
                    currentParam.append(c);
                }
            } else {
                if (c == '"' || c == '\'') {
                    inString = true;
                    stringChar = c;
                } else if (c == ',') {
                    if (currentParam.length() > 0) {
                        String param = currentParam.toString().trim();
                        params.add(parseSingleParameter(param));
                        currentParam = new StringBuilder();
                    }
                } else {
                    currentParam.append(c);
                }
            }
        }

        // 处理最后一个参数
        if (currentParam.length() > 0) {
            String param = currentParam.toString().trim();
            params.add(parseSingleParameter(param));
        }

        return params.toArray();
    }

    /**
     * 解析单个参数
     */
    private Object parseSingleParameter(String param) {
        if ("null".equals(param)) {
            return null;
        }

        // 处理字符串字面量
        if ((param.startsWith("'") && param.endsWith("'")) ||
                (param.startsWith("\"") && param.endsWith("\""))) {
            return param.substring(1, param.length() - 1);
        }

        // 处理布尔值
        if ("true".equalsIgnoreCase(param)) {
            return true;
        }
        if ("false".equalsIgnoreCase(param)) {
            return false;
        }

        // 处理数字
        try {
            if (param.contains(".")) {
                return Double.parseDouble(param);
            } else {
                return Long.parseLong(param);
            }
        } catch (NumberFormatException e) {
            // 不是数字，返回原始字符串
            return param;
        }
    }

    /**
     * 检查类型兼容性
     */
    private boolean isCompatibleType(Class<?> expected, Class<?> actual) {
        // 如果类名相同，即使类加载器不同也认为是兼容的
        if (expected.getName().equals(actual.getName())) {
            log.debug("类名相同但类加载器不同 - 认为兼容: {} (loader1: {}, loader2: {})",
                    expected.getName(),
                    expected.getClassLoader(),
                    actual.getClassLoader());
            return true;
        }

        // 基本类型与其包装类的兼容性检查
        if (expected.isPrimitive()) {
            if (expected == boolean.class && actual == Boolean.class) return true;
            if (expected == byte.class && actual == Byte.class) return true;
            if (expected == char.class && actual == Character.class) return true;
            if (expected == short.class && actual == Short.class) return true;
            if (expected == int.class && actual == Integer.class) return true;
            if (expected == long.class && actual == Long.class) return true;
            if (expected == float.class && actual == Float.class) return true;
            if (expected == double.class && actual == Double.class) return true;
            return false;
        }

        return expected.isAssignableFrom(actual);
    }

    /**
     * 获取默认返回值
     */
    private Object getDefaultValue(Class<?> returnType) {
        if (returnType == void.class) {
            return null;
        } else if (returnType == boolean.class) {
            return false;
        } else if (returnType == char.class) {
            return '\0';
        } else if (returnType == byte.class || returnType == short.class ||
                returnType == int.class || returnType == long.class ||
                returnType == float.class || returnType == double.class) {
            return 0;
        } else {
            return null;
        }
    }
}